from django.db import models
from django.contrib.auth.models import AbstractUser
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from django.conf import settings

from meiduo_demo_1.utils.BaseModel import BaseModel

# Create your models here.

# 重写用户模型类，继承自AbstractUser
class User(AbstractUser):
    """自定义用户模型类"""

    # 额外增加 mobile 字段
    mobile = models.CharField(max_length=11, unique=True, verbose_name='手机号')

    # 增加email_active 字段
    email_active = models.BooleanField(default=False,
                                       verbose_name='邮箱验证状态')

    # 新增默认地址
    default_address = models.ForeignKey('Address',
                                        related_name='users',
                                        null=True,
                                        blank=True,
                                        on_delete=models.SET_NULL,
                                        verbose_name='默认地址')

    # 对当前表进行相关设置：
    class Meta:
        db_table = 'tb_users'
        verbose_name = '用户'   # 命名为用户
        verbose_name_plural = verbose_name  # 复数形式也叫用户

    # 在 str 魔法方法中。返回用户名称 username
    def __str__(self):
        return self.username




    def generate_token(self,email):
        """加密token, 并生成verify_url"""

        s = Serializer(settings.SECRET_KEY, expires_in=60 * 60 * 24)

        # 拼接参数
        data = {'user_id': self.id, 'email': self.email}

        # 加密生成 token 值,这个值时bytes 类型, 所以解码为str:
        token = s.dumps(data)
        token = token.decode()

        # 拼接verify_url
        verify_url = settings.EMAIL_VERIFY_URL + token

        return verify_url

    @staticmethod
    def check_token(token):
        """解码并验证token"""

        # 验证token
        s = Serializer(settings.SECRET_KEY, expires_in=60 * 60 * 24)

        try:
            data = s.loads(token)
        except Exception as e:
            # 如果token 中没有值,则报错
            return None
        else:
            # 如果token 中有值,则获取
            user_id = data.get('user_id')
            email = data.get('email')

        # 从User 表中获取对应的用户
        try:
            user = User.objects.get(id=user_id, email=email)
        except Exception as e:
            # 用户不存在,返回None
            return None
        return user


class Address(BaseModel):
    """用户地址"""

    user = models.ForeignKey(User,
                             on_delete=models.CASCADE,
                             related_name='addresses',
                             verbose_name='用户')

    province = models.ForeignKey('areas.Areas',
                                 on_delete=models.PROTECT,
                                 related_name='province_addresses',
                                 verbose_name='省')

    city = models.ForeignKey('areas.Areas',
                             on_delete=models.PROTECT,
                             related_name='city_addresses',
                             verbose_name='市')

    district = models.ForeignKey('areas.Areas',
                                 on_delete=models.PROTECT,
                                 related_name='district_addresses',
                                 verbose_name='区')

    title = models.CharField(max_length=20, verbose_name='地址名称')
    receiver = models.CharField(max_length=20, verbose_name='收货人')
    place = models.CharField(max_length=50, verbose_name='地址')
    mobile = models.CharField(max_length=11, verbose_name='手机')
    tel = models.CharField(max_length=20,
                           null=True,
                           blank=True,
                           default='',
                           verbose_name='固定电话')

    email = models.CharField(max_length=30,
                             null=True,
                             blank=True,
                             default='',
                             verbose_name='电子邮箱')

    is_deleted = models.BooleanField(default=False, verbose_name='逻辑删除')

    class Meta:
        db_table = 'tb_address'
        verbose_name = '用户地址'
        verbose_name_plural = verbose_name
        ordering = ['-update_time']



# # 设置密码
# User.set_password()
#
# # 校验密码
# User.check_password()
#
# # 验证用户登录
#
# from django.contrib.auth import authenticate
# # suthenticate(username=username, password=password) 传入用户名和密码，传统身份认证
# User.objects.create(username= 'XXX', password='XX')  # 密码不会自动加密
# User.objects.create_user(username= 'XXX', password='XX')  # 密码会自动加密
